
try:
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
except ImportError:
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *

# from lxml import etree,objectify

import numpy as np
import os,sys
import json
import threading 
import re 

class list_item(QWidget):
    # released = pyqtSignal(QWidget)  # 建立一个点击信号
    # type = 0 file, = 1 dir, 
    def __init__(self, photo, data, ftype, pose):
        super().__init__()
        self.file_path = data
        self.file_name = os.path.basename(data)
        hlay = QHBoxLayout()
        intent_l = QLabel()
        # print('intent: ', pose[0])
        intent_l.setFixedWidth(10*(pose[0]))
        hlay.addWidget(intent_l)
        self.map_l = QLabel()
        self.map_l.setFixedSize(10, 10)
        self.set_pic(photo)
        hlay.addWidget(self.map_l)
        hlay.addWidget(QLabel(self.file_name))
        hlay.setContentsMargins(0, 0, 0, 0)
        self.setLayout(hlay)
        self.type = ftype
        self.pose = pose 
        self.content = []
        self.is_open = 0

    def set_pic(self,img_path):
        maps = QPixmap(img_path).scaled(10, 10)
        self.map_l.setPixmap(maps)

class dir_content(QWidget):
    
    clk_path = pyqtSignal(str)
    # s_clk_dir = pyqtSignal(QListWidgetItem)

    def __init__(self,content):
        super().__init__()
        self.filedir =  os.path.dirname(__file__)
        self.load_type_file()
        self.ss = QListWidget(self)
        self.ss.itemClicked.connect(self.item_clicked)

        # self.ss.setFixedSize(300,600)
        self.add_list_path(content, -1)
            
        # self.menu_frame = QFrame(self)
        vlay = QHBoxLayout(self)
        vlay.addWidget(self.ss)
        vlay.setContentsMargins(0, 0, 0, 0)
        # self.menu_frame.setLayout(vlay)
        # self.resize(300, 600)
        self.setLayout(vlay)

    def open_file(self, item):
        print('open_file')
        it = self.ss.itemWidget(item)
        item_idx = self.ss.indexFromItem(item)
        self.clk_path.emit(it.file_path)
        # print(it.file_path)
        pass 

    def c_dir(self,  item):
        # print('-------------------c_dir-----------------------')
        it = self.ss.itemWidget(item)
        item_idx = self.ss.indexFromItem(item).row()
        self.clk_path.emit(it.file_path)
        # print(self.ext['dir'])
        path = it.file_path 

        if it.is_open == 0:
            self.add_list_path(path, item_idx)
            it.set_pic(self.ext['dir']['ncarei']['none']['open']['icon'])
            it.is_open += 1
        else:
            self.del_content(item_idx)
            self.ss.itemWidget(item).set_pic(self.ext['dir']['ncarei']['none']['close']['icon'])
            it.is_open -= 1
        # print('-------------------end c_dir-----------------------')
        # print()

    def del_content(self, item_idx):
        item = self.ss.item(item_idx)
        tw = self.ss.itemWidget(item).pose
        slen = tw[3] if tw[1] == 0 else tw[1] -1
        # print('slen:', slen)
        # 更新父节点的兄弟
        # ni = item.pose[1]
        pw = item
        t = self.ss.itemWidget(pw).pose
        while t[2] != 0:
            pw_i = self.ss.indexFromItem(pw).row()+self.ss.itemWidget(pw).pose[2]
            # print('pw_i:',pw_i, self.ss.itemWidget(pw).pose[2], self.ss.itemWidget(pw).file_path)
            pw = self.ss.item(pw_i)#self.ss.itemWidget(pw).pose[0]
            t = self.ss.itemWidget(pw).pose
            # t[1] -= slen 
            t[1] -= 0 if t[1] == 0 else slen 
            # print(t)

        # 更新兄弟节点的父节点

        aw = item
        t = self.ss.itemWidget(aw).pose
        #更新兄弟节点的父节点位置
        while t[1] != 0:
            aw_i = self.ss.indexFromItem(aw).row()+self.ss.itemWidget(aw).pose[1]
            # print('aw_i:',aw_i)
            # print('aw_i:',aw_i, self.ss.itemWidget(aw).pose, self.ss.itemWidget(aw).file_path)
            aw = self.ss.item(aw_i)#self.ss.itemWidget(ppw).pose[0]
            t = self.ss.itemWidget(aw).pose
            # t[2] -= slen 
            t[2] += 0 if t[2] == 0 else slen 
        #     print(t)
        # print(slen, self.ss.itemWidget(item).file_path)
        for i in range(slen):
            s_idx = item_idx+1
            s_item = self.ss.item(s_idx)
            # 删除子节点
            if self.ss != None and s_item != None:
                self.ss.removeItemWidget(
                    self.ss.takeItem(self.ss.row(s_item)))
        tw[3]  = 0
        tw[1] = 1

    def item_clicked(self, item):
        it = self.ss.itemWidget(item)
        self.ets = {0: self.open_file, 1: self.c_dir}
        if it.type not in self.ets:
            return 
        self.ets[it.type](item)

    def add_list_path(self, path, parent_index):
        lft = os.listdir(path)
        fs = []
        for f in lft:
            fs.append(os.path.join(path, f))

        ws = self.classify_path(fs)
        self.add_listw(ws, parent_index)

    def add_listw(self, wights, parent_index):
        p_i = parent_index 
        wsl = len(wights)
        c_i = 0
        if p_i >= 0:
            pw = self.ss.itemWidget(self.ss.item(p_i))
            # pw.pose[3]  = 1
            ppw = self.ss.item(p_i)
            t = self.ss.itemWidget(ppw).pose
            #更新父节点的兄弟位置
            while t[2] != 0:
                # print('pw',pw.pose)
                ppw_i = self.ss.indexFromItem(ppw).row()+self.ss.itemWidget(ppw).pose[2]
                # print('ppw_i:',ppw_i, self.ss.itemWidget(ppw).pose, self.ss.itemWidget(ppw).file_path)
                ppw = self.ss.item(ppw_i)#self.ss.itemWidget(ppw).pose[0]
                t = self.ss.itemWidget(ppw).pose
                # print(t, self.ss.itemWidget(ppw).file_path)
                t[1] += 0 if t[1] == 0 else wsl 
                # t[1] += wsl 
                # print(t)

            apw = self.ss.item(p_i)
            t = self.ss.itemWidget(apw).pose
            #更新兄弟节点的父节点位置
            while t[1] != 0:
                apw_i = self.ss.indexFromItem(apw).row()+self.ss.itemWidget(apw).pose[1]
                # print('apw_i:',apw_i)
                # print('apw_i:',apw_i, self.ss.itemWidget(apw).pose, self.ss.itemWidget(apw).file_path)
                apw = self.ss.item(apw_i)#self.ss.itemWidget(ppw).pose[0]
                t = self.ss.itemWidget(apw).pose
                t[2] -= 0 if t[2] == 0 else wsl 
                # print(t)

            pw.pose[3] = wsl #
            pw.pose[1] += 0 if pw.pose[1] == 0 else wsl 
            # print('add pw:', pw.pose, wsl)
            c_i = pw.pose[0] + 1
            # if pw.pose[1] != 0:
            #     pwa = self.ss.itemWidget(self.ss.item(p_i+1))
            #     pwa.pose[1]  = -(wsl+1)
        # 展示孩子节点
        for wi, w_arg in enumerate(wights):

            wzf = 0 if wi == wsl-1 else 1
            pf = 0 if p_i == -1 else -wi-1

            # 当前层数，后一个的相对位置，上一级位置， 后一级位置
            pose = [c_i, wzf, pf, 0]
            w = list_item(*w_arg[:3], pose)

            item = QListWidgetItem()
            item.setSizeHint(QSize(200, 20))
            self.ss.insertItem(p_i + wi+1, item)
            
            self.ss.setItemWidget(item, w)
            # print(w.pose)


    def load_type_file(self):
        t = {}
        cnf = os.path.join(self.filedir, '../data/icon/icon.cnf')
        
        with open(cnf) as fr:
            cnf_j = json.load(fr)
            
        for ck in cnf_j:
            ce = cnf_j[ck]
            for e in  cnf_j[ck]['match']:
                if e['key'] == '':
                    continue 
                
                if e['type'] not in t:
                    t[e['type']] = {'carei': {}, 'ncarei': {}}
                # 是否有大小写
                if e['carei']:
                    tt = t[e['type']]['carei']
                    te = e['key']
                else:
                    tt = t[e['type']]['ncarei']
                    te = e['key'].lower()
                # 匹配后缀
                if te not in tt:
                    tt[te] = {}

                if ce['status'] not in tt[te]:
                    tt[te][ce['status']] = {'icon': ck, 'type': ce['type']}
        self.ext = t
        
    def get_dir_type(self, dir_path):
        return None
    
    def match_type(self, tys, k, t):
        tp = None
        if k in tys['carei']:
            tc = tys['carei'][k]
            if t in tc:
                tp =  tc[t]
            elif 'awaly' in tc:
                tp = tc['awaly']
        elif k in tys['ncarei']:
            tc = tys['ncarei'][k]
            if t in tc:
                tp = tc[t]
            elif 'awaly' in tc:
                tp = tc['awaly']
            else:
                tp = None
        elif 'none' in tys['ncarei']:
            tc = tys['ncarei']['none']
            if t in tc:
                tp = tc[t]
            elif 'awaly' in tc:
                tp = tc['awaly']
            else:
                tp = None
        else:
            tp = None
        return tp

    def classify_path(self, paths:list):
        t, dlist, flist = self.ext,[],[]
        for tp in paths:
            if isinstance(tp, list):
                p = tp[0]
                pt = tp[1]
            elif isinstance(tp, str):
                p = tp
                pt = 'close'
            else:
                print('unkonw path type:', tp)
                continue

            p = os.path.abspath(p)
            f = os.path.basename(p)
            s = os.path.splitext(p)
            # print(t['dir'])
            if os.path.isdir(p):
                ty = self.get_dir_type(p)
                tye = self.match_type(self.ext['dir'], ty, pt)
                if tye == None:
                    print('none type dir!')
                    continue
                iw = [tye['icon'], p, 1]
                # iw = list_item(tye['icon'], p, ftype=1, intent=intent)
                # iw.released.connect(self.event_dir_click)
                dlist.append(iw)
            elif os.path.isfile(p):
                tye = self.match_type(self.ext['file'], f, pt)
                if tye is None:
                    ty = self.get_dir_type(p)
                    tye = self.match_type(self.ext['ext'], ty, pt)
                if tye is None:
                    print('none type file!')
                    continue
                iw = [tye['icon'], p, 0]
                # iw = list_item(tye['icon'], p, intent=intent)
                flist.append(iw)
            else:
                print('unkown path')
        dlist = sorted(dlist, key=lambda x: x[1])
        flist = sorted(flist, key=lambda x: x[1])
        # print(dlist,flist)
        return dlist+flist
if __name__ == '__main__':
    app = QApplication(sys.argv)
    d = '.'
    ex = dir_content(d)
    ex.show()
    sys.exit(app.exec_())



